package plugin

import (
	"context"
	"net/http"
	"sync"
)

// Plugin 定义插件接口
type Plugin interface {
	// Name 返回插件名称
	Name() string

	// Version 返回插件版本
	Version() string

	// Init 初始化插件
	Init(ctx context.Context, config map[string]interface{}) error

	// Start 启动插件
	Start() error

	// Stop 停止插件
	Stop() error

	// HandleRequest 处理请求的钩子
	HandleRequest(next http.Handler) http.Handler
}

// Manager 插件管理器
type Manager struct {
	plugins map[string]Plugin
	configs map[string]map[string]interface{}
	mu      sync.RWMutex
}

func NewManager() *Manager {
	return &Manager{
		plugins: make(map[string]Plugin),
		configs: make(map[string]map[string]interface{}),
	}
}

func (m *Manager) Register(p Plugin) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	name := p.Name()
	if _, exists := m.plugins[name]; exists {
		return ErrPluginAlreadyExists
	}

	m.plugins[name] = p
	return nil
}

func (m *Manager) Get(name string) (Plugin, bool) {
	m.mu.RLock()
	defer m.mu.RUnlock()

	p, ok := m.plugins[name]
	return p, ok
}

func (m *Manager) LoadConfig(name string, config map[string]interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()

	m.configs[name] = config
}

func (m *Manager) InitAll(ctx context.Context) error {
	m.mu.RLock()
	defer m.mu.RUnlock()

	for name, p := range m.plugins {
		if err := p.Init(ctx, m.configs[name]); err != nil {
			return err
		}
	}
	return nil
}

func (m *Manager) StartAll() error {
	m.mu.RLock()
	defer m.mu.RUnlock()

	for _, p := range m.plugins {
		if err := p.Start(); err != nil {
			return err
		}
	}
	return nil
}

func (m *Manager) StopAll() error {
	m.mu.RLock()
	defer m.mu.RUnlock()

	for _, p := range m.plugins {
		if err := p.Stop(); err != nil {
			return err
		}
	}
	return nil
}
